package servlet;

import javax.ejb.EJB;
import javax.naming.*;




import dao.exceptions.NonexistentEntityException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import javax.naming.NamingException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import persistencia.Mensaje;
import persistencia.Usuario;
import sessions.EditarBean;
import sessions.ListaMensajesBean;
import sessions.ListaMensajesBeanLocal;
import sessions.ListaMensajesBeanRemote;
import sessions.ListaUsuariosBean;
import sessions.ListaUsuariosBeanRemote;
import sessions.LogInBean;
import sessions.NuevoUsuarioBean;
import sessions.NuevoUsuarioBeanLocal;
//jms
import javax.jms.*;
import javax.naming.*;
import javax.annotation.Resource;
import java.util.*;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;

public class Control extends HttpServlet {

    @EJB
    private ListaMensajesBeanRemote listaMensajesBean;
    private static ServletContext sc;
    private static String WEBMASTER_EMAIL;
    private boolean depuracion;



    //jms
    @Resource(mappedName = "jms/queueFactory")
    javax.jms.QueueConnectionFactory queueConnectionFactory;
    @Resource(mappedName = "jms/queue")
    javax.jms.Queue queue;
    Connection connectionListener = null;
    QueueSession sessionListener = null;
    QueueReceiver receptorListener = null;
    //fin jms

    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        System.out.println("control --> init");
        sc = this.getServletContext();
        // Obtener el email del webmaster del parametro del contexto y almacenarlo como variable global
        WEBMASTER_EMAIL = (String) sc.getInitParameter("WEBMASTER_EMAIL");
        // Establece el paramero inicial ServletDebug que determina si enviamos los mensajes a la consola
        String depuracionString = config.getInitParameter("ServletDebug");
        //System.out.println("Estamos en Control");
        if (depuracionString.equalsIgnoreCase("true")) {
            depuracion = true;
        } else {
            depuracion = false;
        }
        // Envia los parametros a la consola si esta activada la depuracion
        if (depuracion) {
            System.err.println("Recibido parametro de configuracion: WEBMASTER_EMAIL: " + WEBMASTER_EMAIL);
        }
    }

    @Override
    protected void service(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
        System.out.println("control --> service");
        respuesta.setContentType("text/html");
        System.out.println("Estamos en Control");
        String operacion = peticion.getParameter("operacion");
        System.out.println(operacion);
        // recibe parametro que indica el tipo de operacion
        // si null, pone en operacion la cadena vacia
        if (operacion == null) {
            operacion = "";
        }
        System.err.println("Control servlet operacion --> " + operacion);
        if (operacion.equalsIgnoreCase("principal")) {
            this.doIrPrincipal(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("enviarNuevoMensaje")) {
            this.doEnviarNuevoMensaje(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("nuevoMensaje")) {
            this.doNuevoMensaje(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("responderMensaje")) {
            this.doResponderMensaje(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("guardarEdicion")) {
            this.doGuardarEdicion(peticion, respuesta);
            return;
        }

        if (operacion.equalsIgnoreCase("editarDatos")) {
            this.doEditarDatos(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("logOut")) {
            this.doLogOut(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("alta")) {
            System.out.println("doAltaRegistrarse");
            this.doAltaUsuario(peticion, respuesta);
            //this.doRegistrarse(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("loginUsuario")) {
            //peticion.setAttribute(nombre_usuario, sc);
            this.doLogin(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("altaUsuario")) {
            this.doAltaUsuario(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("recordarPassword")) {
            this.doRecordarPassword(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("subirFichero")) {
            this.doSubirFichero(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("verFicheros")) {
            this.doVerFicheros(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("descargarFichero")) {
            this.doDescargarFichero(peticion, respuesta);
            return;
        }
        if (operacion.equalsIgnoreCase("verMensajes")) {
            try {
                System.err.println("Control --> vamos doVerMensajes");
                this.doVerMensajes(peticion, respuesta);
            } catch (NamingException ex) {
                ex.printStackTrace();
            }
            return;
        }
        if (operacion.equalsIgnoreCase("verBroadcasts")) {
            try {
                System.err.println("Control --> vamos doBroadcasts");
                this.doBroadcasts(peticion, respuesta);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return;
        }
        //jms
        if (operacion.equalsIgnoreCase("enviar")) {
            this.doEnviar(peticion, respuesta);
            return;
        }

        if (operacion.equalsIgnoreCase("listar")) {
            this.doListar(peticion, respuesta);
            return;
        }

        /*if (operacion.equalsIgnoreCase("recibir")) {
            this.doRecibir(peticion, respuesta);
            return;
        }

        if (operacion.equalsIgnoreCase("activar")) {
            this.doActivar(peticion, respuesta);
            return;
        }*/
        // Si se desconoce la operacion recibida
        this.doDesconocida(peticion, respuesta);
        return;
    }

    //jms
     public void doEnviar(HttpServletRequest request, HttpServletResponse response) {
        try {
            System.err.println("Control --> vamos doEnviarMsgInstantaneo");
            String text = request.getParameter("mensaje");
            Connection connection = queueConnectionFactory.createConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            TextMessage message = session.createTextMessage(text);
            MessageProducer producer = session.createProducer(queue);
            producer.send(message);
            producer.close();
            session.close();
            connection.close();
            String texto = "Se ha enviado el mensaje correctamente";
            request.setAttribute("texto1", texto);
            Usuario usuario = (Usuario) sc.getAttribute("usuario");
            RequestDispatcher rd = sc.getRequestDispatcher("/receptor.jsp?nombre_usuario=" + usuario.getNombre() + "&estado=" + sc.getAttribute("estado"));
            rd.forward(request, response);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    public void doListar(HttpServletRequest request, HttpServletResponse response) {
        try {
            System.err.println("Control --> vamos doListar");
            String texto = "";
            Connection connection = queueConnectionFactory.createConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            QueueBrowser browser = session.createBrowser(queue);
            Enumeration queueEnum = browser.getEnumeration();
            System.err.println("Control --> vamos doListar2");
            while (queueEnum.hasMoreElements()) {
                Object obj = queueEnum.nextElement();
                if (obj instanceof TextMessage) {
                    texto += "Mensaje: " + ((TextMessage) obj).getText() + "<br>";
                }
            }
            System.err.println("Control --> vamos doListar3");
            browser.close();
            session.close();
            connection.close();
            request.setAttribute("texto", texto);
            System.err.println("Control --> vamos doListar4");
            Usuario usuario = (Usuario) sc.getAttribute("usuario");
            RequestDispatcher rd = sc.getRequestDispatcher("/receptor.jsp?nombre_usuario=" + usuario.getNombre() + "&estado=" + sc.getAttribute("estado"));
            rd.forward(request, response);

        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    //fin jms

    public void doBroadcasts(HttpServletRequest peticion, HttpServletResponse respuesta) {
        try {
            Usuario usuario = (Usuario) sc.getAttribute("usuario");
            RequestDispatcher rd = sc.getRequestDispatcher("/receptor.jsp?nombre_usuario=" + usuario.getNombre() + "&estado=" + sc.getAttribute("estado"));
            rd.forward(peticion, respuesta);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public void doIrPrincipal(HttpServletRequest peticion, HttpServletResponse respuesta) {
        try {
            Usuario usuario = (Usuario) sc.getAttribute("usuario");
            RequestDispatcher rd = sc.getRequestDispatcher("/principalUsuario.jsp?nombre_usuario=" + usuario.getNombre() + "&estado=" + sc.getAttribute("estado"));
            rd.forward(peticion, respuesta);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void doEnviarNuevoMensaje(HttpServletRequest peticion, HttpServletResponse respuesta) {
        try {
            String destinatario = peticion.getParameter("select");
            String contenido = peticion.getParameter("contenido");
            System.err.println("Destinatario --> " + destinatario + "; Contenido --> " + contenido);
            Usuario usuario = (Usuario) sc.getAttribute("usuario");
            ArrayList usuarios = (ArrayList) sc.getAttribute("usuarios");
            System.err.println("control --> doEnviarNuevoMensaje --> " + usuarios.size());

            Context context = new InitialContext();
            //coche = (CocheBeanRemote)context.lookup("coche.CocheBeanRemote");
            //listaMensajesBean = (ListaMensajesBeanRemote) context.lookup("listaMensajesBean.ListaMensajesBeanRemote");
            listaMensajesBean = new ListaMensajesBean();
            //ListaMensajesBeanLocal lmbr = new ListaMensajesBean();
            System.err.println("control --> doEnviarNuevoMensaje1");
            boolean res = listaMensajesBean.enviarNuevoMensaje(contenido, contenido, Integer.valueOf(destinatario), usuario, usuarios);
            System.err.println("control --> doEnviarNuevoMensaje2");
            if (res) {
                System.err.println("control --> doEnviarNuevoMensaje3");
                doVerMensajes(peticion, respuesta);
            } else {
                System.err.println("control --> doEnviarNuevoMensaje4");
                sc.setAttribute("estado", "errorEnvioMensaje");
                RequestDispatcher rd = sc.getRequestDispatcher("/error.jsp?estado=" + sc.getAttribute("estado"));
                rd.forward(peticion, respuesta);
            }
        } catch (Exception e) {
            e.getStackTrace();
        }
    }

    public void doNuevoMensaje(HttpServletRequest peticion, HttpServletResponse respuesta) {
        try {
            Usuario usuario = new Usuario();
            usuario = (Usuario) sc.getAttribute("usuario");
            ListaUsuariosBeanRemote listaMensajesBean = new ListaUsuariosBean();
            ArrayList listaUsuarios = new ArrayList();
            listaUsuarios = listaMensajesBean.getUsuarios();
            System.err.println("Tam lista --> " + listaUsuarios.size());
            peticion.setAttribute("usuarios", listaUsuarios);
            sc.setAttribute("usuarios", listaUsuarios);
            RequestDispatcher rd = sc.getRequestDispatcher("/nuevoMensaje.jsp?nombre_usuario=" + usuario.getNombre() + "&estado=" + sc.getAttribute("estado"));
            rd.forward(peticion, respuesta);
        } catch (Exception e) {
            e.getStackTrace();
        }
    }

    public void doResponderMensaje(HttpServletRequest peticion, HttpServletResponse respuesta) {
        try {
            int idMensaje = Integer.parseInt(peticion.getParameter("id"));
            ArrayList mensajes = (ArrayList) sc.getAttribute("mensajes");
            Iterator iterador = mensajes.listIterator();
            boolean encontrado = false;
            Mensaje mensaje = null;
            while (iterador.hasNext() && !encontrado) {
                mensaje = (Mensaje) iterador.next();
                if (mensaje.getId() == idMensaje) {
                    encontrado = true;
                }
            }
            Usuario usuario = (Usuario) sc.getAttribute("usuario");

            Mensaje mensajeActual = new Mensaje();
            mensajeActual.copy(mensaje);
            mensajeActual.setContenido((String) peticion.getParameter("respuesta"));
            if (usuario.getId() == mensaje.getIdDestino()) {
                mensajeActual.setIdDestino(mensaje.getIdOrigen());
                mensajeActual.setIdOrigen(mensaje.getIdDestino());
                mensajeActual.setNombreOrigen(mensaje.getNombreDestino());
                mensajeActual.setNombreDestino(mensaje.getNombreOrigen());
            }
            ListaMensajesBean lmb = new ListaMensajesBean();
            boolean resultado = lmb.responderMensajes(mensajeActual);
            if (resultado) {
                System.out.println("vamos a listamensajes");
                doVerMensajes(peticion, respuesta);
            }

        } catch (Exception e) {
            e.getStackTrace();
        }

    }

    public void doGuardarEdicion(HttpServletRequest peticion, HttpServletResponse respuesta) {
        try {
            Usuario nuevoUsuario, usuario;
            nuevoUsuario = new Usuario();
            usuario = (Usuario) sc.getAttribute("usuario");
            nuevoUsuario.setNombre(peticion.getParameter("nombre_usuario"));
            nuevoUsuario.setApellidos(peticion.getParameter("apellidos"));
            nuevoUsuario.setEmail(peticion.getParameter("email"));
            nuevoUsuario.setPassword(peticion.getParameter("password"));

            EditarBean eb = new EditarBean();
            eb.actualizar(usuario, nuevoUsuario);

            RequestDispatcher rd = sc.getRequestDispatcher("/editarDatosUsuario.jsp?nombre_usuario=" + usuario.getNombre() + "&apellidos=" + usuario.getApellidos() + "&email=" + usuario.getEmail() + "&password=" + usuario.getPassword() + "&estado=" + sc.getAttribute("estado"));
            rd.forward(peticion, respuesta);
        } catch (Exception e) {
            System.err.println("doGuardarEdicion -> " + e.getMessage());
        }
    }

    public void doLogOut(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
        RequestDispatcher rd = sc.getRequestDispatcher("/index.jsp");
        rd.forward(peticion, respuesta);
    }

    public void doEditarDatos(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
        Usuario usuario = (Usuario) sc.getAttribute("usuario");
        System.err.println("Email --> " + usuario.getEmail());
        System.err.println("usuario --> " + usuario.getNombre());
        RequestDispatcher rd = sc.getRequestDispatcher("/editarDatosUsuario.jsp?nombre_usuario=" + usuario.getNombre() + "&apellidos=" + usuario.getApellidos() + "&email=" + usuario.getEmail() + "&password=" + usuario.getPassword() + "&estado=" + sc.getAttribute("estado"));


        rd.forward(peticion, respuesta);
    }

    /*public void doLogOut(HttpServletRequest petiocion, HttpServletResponse respuesta) throws ServletException,IOException, NamingException{

    }*/
    private void doVerMensajes(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException, NamingException {
        //RecuperarFicherosBean sf = new RecuperarMssBean();  TODO

        Usuario usuario = (Usuario) sc.getAttribute("usuario");
        System.out.println("Control --> antes de inicializar listaMensajesBean");
        //ListaMensajesBeanLocal lmbl = new ListaMensajesBean();

        Context context = new InitialContext();
        //listaMensajesBean = (ListaMensajesBeanRemote) context.lookup("listaMensajesBean.ListaMensajesBeanRemote");
        listaMensajesBean = new ListaMensajesBean();
        System.out.println("Control --> antes de coger los mensajes");
        ArrayList listaMensajes = listaMensajesBean.getMensajes(usuario);
        //System.out.println("Control --> antes de ir a listaMensajes.jsp --> " + listaMensajes.size());
        peticion.setAttribute("mensajes", listaMensajes);
        sc.setAttribute("mensajes", listaMensajes);
        RequestDispatcher rd = sc.getRequestDispatcher("/listaMensajes.jsp?nombre_usuario=" + usuario.getNombre() + "&estado=" + sc.getAttribute("estado"));
        rd.forward(peticion, respuesta);
    }

    private void doDescargarFichero(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
    }

    private void doRecordarPassword(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
        System.out.println(peticion.getParameter("email"));
        //loginBean.recordarPassword(peticion.getParameter("email"));
    }

    private void doVerFicheros(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
    }

    private void doSubirFichero(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
    }

    private void doLogin(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
        LogInBean lib = new LogInBean();
        String email = peticion.getParameter("emailLog");
        //String nombre_usuario = lib.login(email, peticion.getParameter("passwordLog"));
        Usuario usuario = lib.login(email, peticion.getParameter("passwordLog"));
        System.err.println("Usuario --> " + usuario.getNombre());

        if (usuario.getNombre() != null) {
            sc.setAttribute("usuario", usuario);
            sc.setAttribute("estado", "conectado");
            //sc.setAttribute("nombre_usuario", nombre_usuario);

            //sc.setAttribute("apellidos", sc)
            //sc.setAttribute("email_usuario", email);
            RequestDispatcher rd = sc.getRequestDispatcher("/principalUsuario.jsp?nombre_usuario=" + usuario.getNombre() + "&estado=" + sc.getAttribute("estado"));
            rd.forward(peticion, respuesta);
        } else {
            sc.setAttribute("estado", "errorLogin");
            RequestDispatcher rd = sc.getRequestDispatcher("/error.jsp?estado=" + sc.getAttribute("estado"));
            rd.forward(peticion, respuesta);
        }
    }

    private void doAltaUsuario(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {

        String nombre, apellidos, email, password;
        nombre = peticion.getParameter("nombre");
        apellidos = peticion.getParameter("apellidos");
        email = peticion.getParameter("password");
        password = peticion.getParameter("email");
        NuevoUsuarioBeanLocal nub = new NuevoUsuarioBean();
        int res = nub.aniadir(nombre, apellidos, password, email);
        if (res != -1) {
            sc.setAttribute("estado", "conectado");
            Usuario usuario = new Usuario();
            usuario.setNombre(nombre);
            usuario.setApellidos(apellidos);
            usuario.setEmail(email);
            usuario.setPassword(password);
            sc.setAttribute("usuario", usuario);
            System.out.println("usuario --> " + nombre);
            RequestDispatcher rd = sc.getRequestDispatcher("/principalUsuario.jsp?nombre_usuario=" + nombre + "&estado=" + sc.getAttribute("estado"));
            rd.forward(peticion, respuesta);
        } else {
            Usuario usuario = new Usuario();
            usuario.setNombre(nombre);
            usuario.setApellidos(apellidos);
            usuario.setEmail(email);
            sc.setAttribute("usuario", usuario);
            sc.setAttribute("estado", "emailYaExiste");
            RequestDispatcher rd = sc.getRequestDispatcher("/error.jsp?nombre_usuario=" + usuario.getNombre() + "&apellidos=" + usuario.getApellidos() + "&email=" + usuario.getEmail() + "&password=" + usuario.getPassword() + "&estado=" + sc.getAttribute("estado"));
            rd.forward(peticion, respuesta);
        }
    }

    private void doRegistrarse(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
        RequestDispatcher rd = sc.getRequestDispatcher("/Registrarse.jsp");
        rd.forward(peticion, respuesta);
    }

    /*private void doLogin(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
    RequestDispatcher rd = sc.getRequestDispatcher("/login.jsp");
    rd.forward(peticion, respuesta);
    }*/
    private void doDesconocida(HttpServletRequest peticion, HttpServletResponse respuesta) throws ServletException, IOException {
        RequestDispatcher rd = sc.getRequestDispatcher("/error.jsp");
        rd.forward(peticion, respuesta);
    }

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {
            /* TODO output your page here
            out.println("<html>");
            out.println("<head>");
            out.println("<title>Servlet Control</title>");
            out.println("</head>");
            out.println("<body>");
            out.println("<h1>Servlet Control at " + request.getContextPath () + "</h1>");
            out.println("</body>");
            out.println("</html>");
             */
        } finally {
            //out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /**
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    /**
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
        //email = request.getParameter("email");
        //pass = request.getParameter("pass");
    }
    /*public void doPost(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException {
    doGet(request, response);
    }

    public void doGet(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException {
    request.getParameter("login");
    request.getParameter("password");
    }*/

    /**
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>
}
